S3-Pre-Signed-URLでダウンロードした画像を Android の画像ライブラリ Glide 4 でキャッシュする
西田@大阪@Android 修行中 です
今回はAndroidでS3の画像を表示するときにPre-Signed URL つかうと、発行される度にURLが違うためGlideをつかってる場合キャッシュのキーにURLをつかうため、表示するたびにキャッシュされてしまう現象がおきてしまい、その対策を調べました
ためした Glide のバージョンは 4.9 です
GlideのCache
GlideのCacheは2種類あります。
- メモリ上のキャッシュ
- ディスク上のキャッシュ
画像を取得するタイミングでメモリ上にキャッシュがあればメモリ上のキャッシュを返し、次にディスク上のキャッシュがあれば、ディスク上のキャッシュを返し、それすらもなければ Origin のリソースを取得しにいきます
GlideがCacheする単位
2つの要素をキーとして比較します
Model
(File, Uri, Url)- 追加で
Signature
を指定することで同じ Model でも違うものとして扱える
S3-Presingd-URL は発行のたびに毎回異なる一時的なクエリーパラメーターがURLに付与されます
https://example.s3.amazonaws.com/images/1.JPG?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXX&X-Amz-Date=20191018T011014Z&X-Amz-Expires=17760&X-Amz-SignedHeaders=host&X-Amz-Security-Token=XXXX&X-Amz-Signature=XXX
今回はクエリーパラメーターの抜いた https://example.s3.amazonaws.com/images/1.JPG
のみをキーとするようカスタムします
実装
GlideUrl
を継承したクラスを用意し、getCacheKey
メソッドをオーバーライドします
import com.bumptech.glide.load.model.GlideUrl class GlideNoTokenUrl(private val url: String) : GlideUrl(url) { override fun getCacheKey(): String { // Domain(バケット名含む) + Path で判定する return url.substringBefore("?") } }
Glideの load
メソッドに渡すパラメーターにカスタムした GlideNoTokenUrl
のインスタンスを渡します
val url = "https://example.s3.amazonaws.com/...." Glide.with(context) .load(GlideNoTokenUrl(url))
最後に
わかってしまえば簡単なことなのですがなれてないせいかはまってしまいました。誰かのお役に立てれば幸いです
参考
Best strategy to load images using Glide — Image loading library for Android